<template>
	<view>
		<view class="sign-box">
			<canvas class="mycanvas" :style="{width: curWidth + 'px', height: curHeight +'rpx'}" canvas-id="mycanvas"
				@touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
			</canvas>
		</view>
		<view class="sign-btn">
			<button class="btn" @click="handleReturn">撤销</button>
			<button class="btn" @click="handleReset">重写</button>
			<button class="btn" @click="handleConfirm">确认</button>
		</view>
		<image :src="failPath" mode=""></image>
	</view>
</template>

<script>
	// 1、安装：npm i image-tools --save

	// 2、引入：import { pathToBase64, base64ToPath } from 'image-tools'

	// 3、使用：图片转base64（注意事项：如果是网络路径需要先使用下载API下载下来）
	// import {
	// 	pathToBase64
	// } from 'image-tools'
	import {
		pathToBase64,
		base64ToPath
	} from 'image-tools'
	export default {
		data() {
			return {
				curWidth: null,
				curHeight: 600,
				ctx: null,
				pointsList: [], // 路径点
				startPointsList: [], // 开始点
				allPointsList: [], // 所有点
				failPath: null // 文件路径
			};
		},

		onLoad() {
			this.initCanvas()
		},

		methods: {
			// 初始化
			initCanvas() {
				uni.getSystemInfo({
					success: (res) => {
						this.curWidth = res.windowWidth
					}
				})
				this.ctx = uni.createCanvasContext('mycanvas', this)
				this.ctx.lineWidth = 4 // 设置线粗细
				this.ctx.lineCap = 'round' // 设置线圆角
				this.ctx.lineJoin = 'round' // 设置线交叉处圆角
			},

			// 画线
			drawLine(startPoint, endPoint) {
				this.ctx.moveTo(startPoint.X, startPoint.Y)
				this.ctx.lineTo(endPoint.X, endPoint.Y)
				this.ctx.stroke() // 绘制轮廓线
				this.ctx.draw(true) // 将绘制的内容显示到画布
			},

			// 触摸开始
			touchstart(e) {
				const startPoint = {
					PointType: 1,
					X: e.changedTouches[0].x,
					Y: e.changedTouches[0].y
				}
				this.pointsList.unshift(startPoint)
				this.startPointsList.push(startPoint)
				this.allPointsList.push(startPoint)
				this.ctx.beginPath() // 开始画线
			},

			// 触摸移动
			touchmove(e) {
				const movePoint = {
					PointType: 2,
					X: e.changedTouches[0].x,
					Y: e.changedTouches[0].y
				}
				this.pointsList.unshift(movePoint)
				this.allPointsList.push(movePoint)
				if (this.pointsList.length >= 2) this.drawLine(this.pointsList[1], this.pointsList[0])
			},

			// 触摸结束
			touchend() {
				this.pointsList = []
			},

			// 撤销
			handleReturn() {
				// 清除画布内容
				if (!this.allPointsList.length) return
				this.ctx.clearRect(0, 0, this.curWidth, this.curHeight)
				this.ctx.draw(true)
				this.startPointsList = []

				const startPointIndex = []
				this.allPointsList.forEach((item, index) => {
					if (item.PointType == 1) {
						startPointIndex.push(index)
					}
				})
				// 判断存在几条线
				if (startPointIndex.length > 1) {
					// 删除上一条线 并重新绘制剩余的线
					this.allPointsList.splice(startPointIndex[startPointIndex.length - 1])
					this.allPointsList.forEach((item, index) => {
						if (item.PointType == 1) {
							this.ctx.beginPath()
						} else {
							this.drawLine(this.allPointsList[index - 1], item)
						}
					})
				} else {
					this.allPointsList = []
				}
			},

			// 重写
			handleReset() {
				this.ctx.clearRect(0, 0, this.curWidth, this.curHeight) // 清除画布内容
				this.ctx.draw(true)
				this.startPointsList = []
				this.allPointsList = []
			},

			// 确认
			handleConfirm() {
				if (!this.allPointsList.length) return uni.showToast({
					title: '您还未签名',
					icon: 'none',
					mask: true
				})
				uni.canvasToTempFilePath({
					canvasId: 'mycanvas',
					success: (res) => {
						// WX: 临时文件 H5: base64 APP: 本地
						// #ifdef MP-WEIXIN
						// 方式1：
						const fs = uni.getFileSystemManager()
						fs.readFile({
							filePath: res.tempFilePath,
							encoding: 'base64',
							success: res => {
								this.failPath = 'data:image/png;base64,' + res.data
							}
						})
						// 方式2：
						// pathToBase64(res.tempFilePath).then(res => {
						// 	this.failPath = res
						// })
						console.log(res, 'wx');
						// #endif
						// #ifdef H5
						this.failPath = res.tempFilePath
						console.log(res, 'h5');
						// #endif
						// #ifdef APP
						pathToBase64(res.tempFilePath).then(res => {
							this.failPath = res
						})
						console.log(res, 'app');
						// #endif
					}
				})
			}
		}
	}
</script>

<style lang="scss">
	/* 颜色变量 */
	$primary-color: #007AFF;
	$success-color: #34C759;
	$danger-color: #FF3B30;
	$disabled-color: #E5E5EA;

	.sign-btn {
		display: flex;
		justify-content: space-between;
		margin: 40rpx 0;
		padding: 0 30rpx;
		gap: 20rpx; // 按钮间距
	}

	.btn {
		flex: 1;
		height: 80rpx;
		line-height: 80rpx;
		border-radius: 12rpx;
		font-size: 32rpx;
		font-weight: 500;
		transition: all 0.2s ease;
		position: relative;
		overflow: hidden;

		/* 通用交互效果 */
		&::after {
			content: '';
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
			/* 关键居中属性 */
			width: 100%;
			height: 100%;
			background: rgba(0, 0, 0, 0.1);
			opacity: 0;
			transition: opacity 0.2s;
		}

		&:active::after {
			opacity: 1;
		}
	}

	/* 撤销按钮 */
	.btn:nth-child(1) {
		background: linear-gradient(135deg, #FF3B30 0%, #FF625B 100%);
		color: white;
		box-shadow: 0 4rpx 12rpx rgba(255, 59, 48, 0.2);
	}

	/* 重写按钮 */
	.btn:nth-child(2) {
		background: linear-gradient(135deg, #E5E5EA 0%, #F2F2F7 100%);
		color: #8E8E93;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
	}

	/* 确认按钮 */
	.btn:nth-child(3) {
		background: linear-gradient(135deg, #007AFF 0%, #0A84FF 100%);
		color: white;
		box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.2);

		/* 禁用状态 */
		&:disabled {
			background: $disabled-color;
			box-shadow: none;
			color: #AEAEB2;
		}
	}

	/* 画布样式 */
	.mycanvas {
		background-color: #FFFFFF;
		border-radius: 16rpx;
		box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.05);
	}
</style>